#include <iostream>

#if 1
    // 多继承
    class Base1
    {
    public:
        Base1(int a):a(a){}
        void show()
        {
            std::cout<<"a:"<<a<<std::endl;
        }
    protected:
        int a;
    };

    class Base2
    {
    public:
        Base2(int b):b(b){}
        void show()
        {
            std::cout<<"b:"<<b<<std::endl;
        }
    protected:
        int b;
    };

    // 多继承：同时继承自多个类，把它们的函数进行整合操作
    class Derived:public Base1, public Base2
    {
    public:
        Derived(int a, int b):Base1(a), Base2(b){}
        void show()
        {
            // 多继承情况下，这个show必须指明来源
            // 如果不带前缀的命名空间，那一定是调自己的show，父类会全部被遮蔽掉
            Base1::show();
            Base2::show();
        }
    };

    int main()
    {
        // Base1::show(); // 在 C++ 中，非静态成员函数 必须通过对象调用，而不能仅仅通过作用域解析符 :: 直接调用。这是因为 非静态成员函数依赖于具体对象的实例，而不是类本身。
        Derived d(1, 2);
        d.show();
        return 0;
    }
#endif

#if 0
    // 继承顺序
    class Base1
    {
    public:
        Base1(int a):a(a){std::cout<<"Base1\n";}
        void show()
        {
            std::cout<<"a:"<<a<<std::endl;
        }
    protected:
        int a;
    };

    class Base2
    {
    public:
        Base2(int b):b(b){std::cout<<"Base2\n";}
        void show()
        {
            std::cout<<"b:"<<b<<std::endl;
        }
    protected:
        int b;
    };

    // 父类构建顺序和构造函数调用顺序无关，和继承顺序有关
    // 谁先被继承，谁先构建
    class Derived:public Base2, public Base1
    {
    public:
        // 父类构建顺序和构造函数调用顺序无关
        Derived(int a, int b):Base1(a), Base2(b){}
        void show()
        {
            Base1::show();
            Base2::show();
        }
    };

    int main()
    {
        Derived d(1, 2);
        d.show();
        return 0;
    }
#endif

#if 0
    // 菱形继承
    // 两个或两个以上的类继承自同一个类，然后这几个类又构建出一个全新的类
    class UltraBase
    {
    public:
        UltraBase(int c):c(c){}
    protected:
        int c;
    };

    class Base1:public UltraBase
    {
    public:
        Base1(int c, int a):UltraBase(c), a(a){std::cout<<"Base1\n";}
        void show()
        {
            std::cout<<"a:"<<a<<std::endl;
        }
    protected:
        int a;
    };

    class Base2:public UltraBase
    {
    public:
        Base2(int c, int b):UltraBase(c), b(b){std::cout<<"Base2\n";}
        void show()
        {
            std::cout<<"b:"<<b<<std::endl;
        }
    protected:
        int b;
    };

    class Derived:public Base2, public Base1
    {
    public:
        Derived(int c, int a, int b):Base1(c, a), Base2(c, b)
        {
            // 二义性问题（一个变量含有两个含义）
            // this->c++; // Derived c不明确
            this->Base1::c++; // 这样可以解决，但也不合理（明明只要一个c，但最终包含两个c，如果继承的越多，那就会有更多的c）

            // 应该保证UltraBase在不管是它的任何派生类中应该都只有一个c
        }
        void show()
        {
            Base1::show();
            Base2::show();
        }
    };

    int main()
    {
        Derived d(3, 1, 2);
        d.show();
        return 0;
    }
#endif

#if 0
    // 菱形继承的二义性问题的解决方案：虚继承
    class UltraBase
    {
    public:
        UltraBase(int c):c(c){}
    protected:
        int c;
    };

    // 虚继承
    class Base1:virtual public UltraBase
    {
    public:
        Base1(int c, int a):UltraBase(c), a(a){std::cout<<"Base1\n";}
        void show()
        {
            std::cout<<"a:"<<a<<std::endl;
        }
    protected:
        int a;
    };

    class Base2:virtual public UltraBase
    {
    public:
        Base2(int c, int b):UltraBase(c), b(b){std::cout<<"Base2\n";}
        void show()
        {
            std::cout<<"b:"<<b<<std::endl;
        }
    protected:
        int b;
    };

    class Derived:public Base2, public Base1
    {
    public:
        // 现在构建这个c，不再是通过Base1和Base2，要单独对它进行构建
        Derived(int c, int a, int b):UltraBase(c), Base1(c, a), Base2(c, b)
        {
            
        }
        void show()
        {
            Base1::show();
            Base2::show();
            std::cout<<"c:"<<c<<std::endl; // 现在这个c直接来源于UltraBase
        }
    };

    int main()
    {
        Derived d(3, 1, 2);
        d.show();
        return 0;
    }
#endif